package edu.cmu.ece.ds.droidchat;

import java.io.IOException;
import java.net.MalformedURLException;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.facebook.android.DialogError;
import com.facebook.android.Facebook;
import com.facebook.android.Facebook.DialogListener;
import com.facebook.android.FacebookError;

import edu.cmu.ece.ds.droidchat.NetworkService.LocalBinder;
import edu.cmu.ece.ds.droidchat.message.ClientLoginResponseMessage;
import edu.cmu.ece.ds.droidchat.model.StringConstants;
import edu.cmu.ece.ds.droidchat.model.UserInfo;
import edu.cmu.ece.ds.droidchat.util.FacebookJsonParser;
import edu.cmu.ece.ds.droidchat.util.Toolbox;

public class LogInActivity extends Activity {
    private final String TAG = "LogInActivity";

    // facebook object
    private Facebook facebook = Toolbox.getFacebookObject();
    public static Drawable facebookProfilePicture = null;
    private String facebookNickname = null;

    // Layout Views
    private Button mLoginButton;
    private Button mRegisterButton;
    private TextView mUsernameEditText;
    private TextView mPasswordEditText;
    private ImageView mFbImageView;
    private CheckBox mRememberMeCheckBox;

    NetworkService mService; // the Service component
    private boolean mBound = false;
    private ServiceMessageReceiver mReceiver; // the BroadcastReceiver component

    // Progress Dialog
    private boolean isLoggingIn = false;
    private static final int LOGIN = 0;
    private static final int REGISTER = 1;
    private static final int FACEBOOK = 2;

    private class ServiceMessageReceiver extends BroadcastReceiver {
        //public static final String TAG = "ServerMessageReceiver";

        public void onReceive(Context context, Intent intent) {
            Log.d(TAG, "onReceive: " + intent);
            String username = intent
                    .getStringExtra(StringConstants.EXTRA_USERNAME);
            int response = intent
                    .getIntExtra(StringConstants.EXTRA_RESPONSE, 0);
            Log.d(TAG, "username: " + username);
            Log.d(TAG, "response: " + response);

            if (isLoggingIn) {
                dismissDialog(LOGIN);
                if (response == ClientLoginResponseMessage.NO_USER) {
                    Toast.makeText(
                            LogInActivity.this,
                            "Login request with username='"
                                    + username
                                    + "' was NOT successful because username is not registered!",
                            Toast.LENGTH_LONG).show();
                } else if (response == ClientLoginResponseMessage.WRONG_PASSWORD) {
                    Toast.makeText(
                            LogInActivity.this,
                            "Login request with username='"
                                    + username
                                    + "' was NOT successful because password is wrong!",
                            Toast.LENGTH_LONG).show();
                } else {
                    // successful login
                	Log.d(TAG, "successful login");
                    
                	if (mRememberMeCheckBox.isChecked()) {
                        saveLoginInfo(LogInActivity.this, username,
                                mPasswordEditText.getText().toString());
                    } else {
                        clearLoginInfo();
                    }
                	
                    startDroidChatTabActivity(LogInActivity.this, username);
                    Log.d(TAG, "calling finish() because of successful login");
                    finish(); // once the DroidChatTabActivity is started
                                // it means the user has logged in
                                // let's destroy the LogInActivity
                }
            } // else i really don't care
        }
    }

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.login);
        Log.e(TAG, "---onCreate---");

        mLoginButton = (Button) findViewById(R.id.login_button);
        mRegisterButton = (Button) findViewById(R.id.register_button);
        mUsernameEditText = (EditText) findViewById(R.id.user_id);
        mPasswordEditText = (EditText) findViewById(R.id.password);
        mFbImageView = (ImageView) findViewById(R.id.fb_button);
        mRememberMeCheckBox = (CheckBox) findViewById(R.id.remember_password_check_box);

        mReceiver = new ServiceMessageReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction(StringConstants.ACTION_FOR_LOGIN_ACTIVITY);
        this.registerReceiver(mReceiver, filter);
        Log.d(TAG, "ServerMessageReceiver registered!");

        // restore e-mail address and password
        if (savedInstanceState != null) {
            String username = savedInstanceState
                    .getString(StringConstants.EXTRA_USERNAME);
            String password = savedInstanceState
                    .getString(StringConstants.EXTRA_PASSWORD);
            boolean rememberMe = savedInstanceState
                    .getBoolean(StringConstants.PREF_KEY_REMEMBER_ME);
            if (username != null) {
                mUsernameEditText.setText(username);
            }
            if (password != null) {
                mPasswordEditText.setText(password);
            }
            mRememberMeCheckBox.setChecked(rememberMe);
        }
        // Initialize the send button with a listener that for click events
        mLoginButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                String username = mUsernameEditText.getText().toString().trim();
                String password = mPasswordEditText.getText().toString().trim();

                if (validateInput(username, password, LOGIN) == true) {
                    if (mBound == true) {
                        if (mService.isConnectedToServer()) {
                            Log.d(TAG, "mBound is true");
                            isLoggingIn = true;
                            mService.login(username, password);
                            showDialog(LOGIN);
                        } else {
                            // not connected to server
                            Toast.makeText(LogInActivity.this,
                                    R.string.login_error_server_down,
                                    Toast.LENGTH_SHORT).show();

                        }
                    }
                } else {
                    // validateInput() returns false

                }
            }
        });

        mRegisterButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
            	if(mUsernameEditText.getText().toString().contains(" ")){
            		Toast.makeText(LogInActivity.this, R.string.username_space,
                            Toast.LENGTH_SHORT).show();
            		return;
            	}
            	
                String username = mUsernameEditText.getText().toString().trim();
                String password = mPasswordEditText.getText().toString().trim();
                if (validateInput(username, password, REGISTER) == true) {
                    Intent i = new Intent(LogInActivity.this,
                            RegisterActivity.class);
                    i.putExtra(StringConstants.EXTRA_USERNAME, username);
                    i.putExtra(StringConstants.EXTRA_PASSWORD, password);
                    i.putExtra(StringConstants.PREF_KEY_NICKNAME, facebookNickname);
                    i.putExtra(StringConstants.PREF_KEY_REMEMBER_ME,
                            mRememberMeCheckBox.isChecked());
                    startActivity(i);
                }
            }
        });

        mFbImageView.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                if (!facebook.isSessionValid()) {
                    facebook.authorize(LogInActivity.this,
                            new String[] { "email" }, new DialogListener() {
                                @Override
                                public void onComplete(Bundle values) {
                                    showDialog(FACEBOOK);
                                    (new FacebookJsonParser(LogInActivity.this,
                                            facebook)).execute((Void[]) null);
                                }

                                @Override
                                public void onFacebookError(FacebookError error) {
                                }

                                @Override
                                public void onError(DialogError e) {
                                }

                                @Override
                                public void onCancel() {
                                }
                            });
                } else {
                    Log.e(TAG, "HEY! Session still valid");
                    try {
                        facebook.logout(LogInActivity.this);
                        v.performClick();
                    } catch (MalformedURLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                }
            }
        });

    }

    @Override
    public void onStart() {
        super.onStart();
        Log.e(TAG, "---onStart---");

        Intent intent = new Intent(this, NetworkService.class);
        Log.d(TAG, "calling bindService()");
        Toolbox.bindService(this, intent, mConnection,
                Context.BIND_AUTO_CREATE, TAG);

        String[] usernamePassword = retrieveLoginInfo();
        if (usernamePassword != null) {
            mUsernameEditText.setText(usernamePassword[0]);
            mPasswordEditText.setText(usernamePassword[1]);
            mLoginButton.performClick();
        }

    }

    public void onStop() {
        super.onStop();
        Log.e(TAG, "---onStop---");
        Log.d(TAG, "---calling unbindService---");
        Toolbox.unbindService(this, mConnection, TAG);
    }

    protected void onDestroy() {
        super.onDestroy();
        Log.e(TAG, "---onDestroy---");
        unregisterReceiver(mReceiver);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        facebook.authorizeCallback(requestCode, resultCode, data);
    }

    public static void startDroidChatTabActivity(Context context,
            String username) {
        Intent i = new Intent(context, DroidChatTabActivity.class);
        i.putExtra(StringConstants.EXTRA_USERNAME, username);
        context.startActivity(i);
    }

    /** Defines callbacks for service binding, passed to bindService() */
    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName className, IBinder service) {
            // We've bound to TCPService, cast the IBinder and get TCPService
            // instance
            LocalBinder binder = (LocalBinder) service;
            mService = binder.getService();
            // mService.addBoundComponent(LogInActivity.class.getName());
            mBound = true;
            Log.d(TAG, "We've bound to TCPService");

            UserInfo u = Toolbox.getMyInfo();

            if (u != null) {
                // successful login
                startDroidChatTabActivity(LogInActivity.this, u.getUsername());
                Log.d(TAG, "calling finish() because u is not null");
                finish();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mBound = false;
        }
    };

    private boolean validateInput(String username, String password, int button) {
        // Opens Socket to contact the servers
        Log.d(TAG, "Login Button is pressed");
        if (password.length() == 0 || username.length() == 0) {
            if (button == LOGIN) {
                Toast.makeText(this, R.string.login_error_none_entered,
                        Toast.LENGTH_SHORT).show();
            } else if (button == REGISTER) {
                Toast.makeText(this, R.string.register_error_none_entered,
                        Toast.LENGTH_SHORT).show();
            }
        } else {
            Log.d(TAG, username);
            Log.d(TAG, password);

            return true;
        }
        return false;
    }

    protected Dialog onCreateDialog(int id) {
        ProgressDialog dialog;
        switch (id) {
        case LOGIN:
            dialog = new ProgressDialog(LogInActivity.this);
            dialog.setMessage(LogInActivity.this.getText(R.string.login_wait));
            break;
        case FACEBOOK:
            dialog = new ProgressDialog(LogInActivity.this);
            dialog.setMessage(LogInActivity.this
                    .getText(R.string.facebook_wait));
            break;
        default:
            dialog = null;
        }
        return dialog;
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString(StringConstants.EXTRA_USERNAME, mUsernameEditText
                .getText().toString());
        outState.putString(StringConstants.EXTRA_PASSWORD, mPasswordEditText
                .getText().toString());
        outState.putBoolean(StringConstants.PREF_KEY_REMEMBER_ME,
                mRememberMeCheckBox.isChecked());
    }

    public void getRegistrationInfoFromFacebook(UserInfo userInfo) {
        dismissDialog(FACEBOOK);
        mUsernameEditText.setText(userInfo.getUsername());
        facebookProfilePicture = userInfo.getProfilePicture();
        facebookNickname = userInfo.getNickName();
    }

    public static void saveLoginInfo(Context context, String username,
            String password) {
        SharedPreferences pref = PreferenceManager
                .getDefaultSharedPreferences(context);
        SharedPreferences.Editor editor = pref.edit();
        editor.putString(StringConstants.EXTRA_USERNAME, username);
        editor.putString(StringConstants.EXTRA_PASSWORD, password);
        editor.commit();
    }

    private void clearLoginInfo() {
        SharedPreferences pref = PreferenceManager
                .getDefaultSharedPreferences(this);
        SharedPreferences.Editor editor = pref.edit();
        editor.putString(StringConstants.EXTRA_USERNAME, "");
        editor.putString(StringConstants.EXTRA_PASSWORD, "");
        editor.commit();
    }

    private String[] retrieveLoginInfo() {
        SharedPreferences pref = PreferenceManager
                .getDefaultSharedPreferences(this);
        String[] usernamePassword = null;
        String username = pref.getString(StringConstants.EXTRA_USERNAME, "");
        String password = pref.getString(StringConstants.EXTRA_PASSWORD, "");
        if (!username.equals("") && !password.equals("")) {
            usernamePassword = new String[2];
            usernamePassword[0] = username;
            usernamePassword[1] = password;
        }
        return usernamePassword;
    }

}
